package demo08.Synchronized;

/*
 * 卖票案例出现线程安全问题
 * 卖出了不存在的票和相同的票，这显然是离谱的
 * 解决的第二种方案：使用同步方法
 * 使用步骤：
 *      1.把访问了共享数据的代码抽出来放在一个方法中
 *      2.方法上添加synchronized修饰符
 *      格式：
 *      修饰符 synchronized 返回值类型 方法名(参数类型 参数名){
 *      可能出现线程安全的代码
 *      }*/
public class RunnableImpl implements Runnable {
    private static int ticket = 100;
/*
* 静态同步方法
* 锁对象不能是this，静态方法比对象优先创建
* 是RunnableImpl.class*/
    public /*synchronized*/ static void suo() {
        synchronized (RunnableImpl.class) {

            if (ticket > 0) {
                //提高出错概率，小睡一会
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "正在售第" + ticket + "张票");
                ticket--;
            }
        }
    }


    /*
            定义一个同步方法
            同步方法也会把方法内部的代码锁住
            只让一个线程执行
            同步方法的锁对象是谁?
            就是实现类对象 new RunnableImpl()
            也是就是this
         */
  /*  public synchronized void suo() {

        if (ticket > 0) {
            //提高出错概率，小睡一会
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "正在售第" + ticket + "张票");
            ticket--;
        }
    }*/

    @Override
    public void run() {
        while (true) {
            suo();
        }
    }
}


